﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Proggy.Data.Entities;
using System.Web.Mvc;
using Proggy.Web.Cms.Repositories;
using Proggy.Web.Cms.ContentModel;
using Proggy.Web.Cms.Repositories.ContentModel;
using Proggy.Web.Cms.ViewModels;

namespace Proggy.Web.Cms.Service
{
    /// <summary>
    /// Content repo
    /// </summary>
    public interface IContentCrudService
    {
        /// <summary>
        /// Returns the root publishable node
        /// </summary>
        /// <returns></returns>
        PublishableNode GetRootNode();

        /// <summary>
        /// Returns allowed child content model types for the given type
        /// </summary>
        /// <param name="availableType"></param>
        /// <returns></returns>        
        IEnumerable<SelectListItem> GetAllowedChildAvailableTypesSelectList(AvailableContentModel availableType);

        /// <summary>
        /// Get content model type from publishable node id
        /// </summary>
        /// <param name="nodeId"></param>
        /// <returns></returns>
        AvailableContentModel GetAvailableContentModelTypeFromNodeId(int nodeId);

        /// <summary>
        /// Returns select list of available templates
        /// </summary>
        /// <param name="availableType"></param>
        /// <returns></returns>
        IEnumerable<SelectListItem> GetAllowedTemplatesSelectList(AvailableContentModel availableType);

        /// <summary>
        /// Returns content model type from alias
        /// </summary>
        /// <param name="typeAlias"></param>
        /// <returns></returns>
        AvailableContentModel GetAvailableTypeFromTypeAlias(string typeAlias);

        /// <summary>
        /// Create new node (creates publishable (unpublished) and draft)
        /// </summary>
        /// <param name="model"></param>
        /// <param name="parentNodeId"></param>
        /// <param name="errorString"></param>
        /// <param name="newNodeId"></param>
        /// <returns></returns>
        bool CreateNewNode(PublishableNode model, int? parentNodeId, ref string errorString, ref int newNodeId);

        /// <summary>
        /// The content model type repository
        /// </summary>
        IContentModelTypeRepository ContentModelTypeRepository { get; }

        /// <summary>
        /// The content model data repository
        /// </summary>
        IContentModelDataRepository ContentModelDataRepository { get; }

        /// <summary>
        /// Gets allowed child content model types for root node
        /// </summary>
        /// <returns></returns>
        IEnumerable<SelectListItem> GetAllowedRootTypesSelectList();

        /// <summary>
        /// Publish
        /// </summary>
        /// <param name="model"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool PublishDraftContent(IContentModelBase model, string currentUsername, ref string errorMsg);

        /// <summary>
        /// Save draft
        /// </summary>
        /// <param name="model"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool SaveDraftContent(IContentModelBase model, string currentUsername, ref string errorMsg);

        /// <summary>
        /// Delete draft and revert to published
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool RevertToPublished(int nodeId, ref string errorMsg);

        /// <summary>
        /// Returns published node from it's id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        PublishableNode GetPublishableNodeFromId(int id);

        /// <summary>
        /// Trash a node
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool Trash(int nodeId, string currentUsername, ref string errorMsg);

        /// <summary>
        /// Get all trashed content
        /// </summary>
        /// <returns></returns>
        IEnumerable<TrashedNode> GetTrashedContent();

        /// <summary>
        /// Refreshes url cache, cached content and routes
        /// </summary>
        void RefreshRoutesAndCache();

        /// <summary>
        /// Delete trashed content
        /// </summary>
        /// <param name="trashedNodeId"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool DeleteTrashedContent(int trashedNodeId, ref string errorMsg);

        /// <summary>
        /// Returns the content-home view model
        /// </summary>
        /// <returns></returns>
        ContentHomeViewModel GetContentHomeViewModel();

        /// <summary>
        /// Site map view model
        /// </summary>
        /// <param name="open"></param>
        /// <param name="selected"></param>
        /// <param name="includeContentMenu"></param>
        /// <returns></returns>
        SiteMapViewModel GetSiteMapViewModel(string areaId, string open, string selected, bool includeContentMenu, bool useLiveLinksAndNodes);

        /// <summary>
        /// Returns the sort view model for parent id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        SortChildContentViewModel GetSortChildContentViewModel(int id);

        /// <summary>
        /// Save new order
        /// </summary>
        /// <param name="newModel"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        bool SaveNewChildContentModelOrder(SortChildContentViewModel newModel, ref string error);

        /// <summary>
        /// Gets a new version of the view model, with child nodes sorted
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        SortChildContentViewModel GetSortedSortChildContentViewModel(SortChildContentViewModel model, int id);

        /// <summary>
        /// Move content
        /// </summary>
        /// <param name="nodeToMoveId"></param>
        /// <param name="movingToNodeId"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool Move(int nodeToMoveId, int movingToNodeId, ref string errorMsg);

        /// <summary>
        /// Get trashed node by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        TrashedNode GetTrashedNodeById(int id);

        /// <summary>
        /// Restore
        /// </summary>
        /// <param name="model"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        bool RestoreTrashedContent(TrashedNode model, string currentUsername, ref string error, ref int newId);
    }
}
